<template>
    <div v-loading="pageLoading" class="bind-card">
        <div class="bind-card-title">绑定经营者对私银行卡</div>
        <div class="bind-card-desc">
            按照风险合规办法，当个体工商户商家绑定经营者对私银行卡时，宝户通需进行银行预留手机号进行短信验证。
        </div>
        <el-form
            ref="formRef"
            :model="formInfo"
            label-position="right"
            label-width="122px"
            :rules="rules"
            :disabled="disabled"
            class="bind-card-form">
            <el-form-item label="开户名" prop="account_name">
                <span class="ellipsis-overflow">{{ formInfo.account_name || '--' }}</span>
            </el-form-item>
            <el-form-item label="银行卡号" prop="account_public">
                <span class="ellipsis-overflow">{{ formInfo.account_public || '--' }}</span>
            </el-form-item>
            <el-form-item label="银行预留手机号" prop="phone">
                <el-input
                    v-model.number="formInfo.phone"
                    clearable
                    maxlength="11"
                    show-word-limit
                    placeholder="请输入银行预留手机号" />
            </el-form-item>
            <el-form-item label="短信验证码" prop="code" class="auth-code-item">
                <el-input
                    v-model="formInfo.code"
                    clearable
                    placeholder="请输入短信验证码"
                    @input="handleInputNumber"
                    maxlength="10"
                    show-word-limit />
                <el-button
                    link
                    :loading="getAuthCodeLoading"
                    :disabled="Boolean(timeid)"
                    class="suffix-button"
                    @click="getAuthCode">
                    获取验证码 {{ timeid ? `(${second}s)` : '' }}
                </el-button>
            </el-form-item>
            <el-button :loading="submitBindLoading" type="primary" @click="submitForm">确认绑定</el-button>
        </el-form>
    </div>
</template>

<script setup>
import { reactive, ref, onMounted, onUnmounted, onBeforeMount, nextTick } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import dayjs from 'dayjs';
import { ElMessage } from 'element-plus';

import { setLayout, resetLayout } from '@/hooks/layout';
import { getRegExp } from '@/commons/utils';
import request from '@/request/index';

const route = useRoute();
const router = useRouter();
const formRef = ref();

/**
 * 统一处理接口异常的高阶函数
 */
const withRequestError = req => {
    return new Promise((resolve, reject) => {
        req.then(res => {
            const { code, sub_code, msg, data } = res;
            if (code !== 0 || sub_code !== 0) {
                reject(res);
                return ElMessage.error(msg);
            }
            resolve(res);
        }).catch(err => {
            reject(err);
        });
    });
};

/* ----------------------------进入页面之前的校验-start---------------------------- */
const { id } = route.query || {};
// 判断路由是否包含开户名和银行卡号。如果缺失，则返回至列表页
if (!id) {
    ElMessage.warning('缺少商户Id');
    router.replace('/pay/account');
}
/* ----------------------------进入页面之前的校验-end---------------------------- */
const formInfo = reactive({
    id,
    account_name: '',
    account_public: '',
    code: undefined
});

const rules = reactive({
    account_name: [{ required: true, message: '未选择开户名', trigger: 'blur' }],
    account_public: [{ required: true, message: '未选择银行号', trigger: 'blur' }],
    phone: [
        { required: true, message: '请输入银行预留手机号', trigger: 'blur' },
        { pattern: getRegExp('phone'), message: '银行预留手机号格式不正确', trigger: 'blur' }
    ],
    code: [{ required: true, message: '请输入短信验证码', trigger: 'blur' }]
});

const submitBindLoading = ref(false);
const submitForm = async () => {
    try {
        submitBindLoading.value = true;
        await formRef.value.validate();
        await withRequestError(
            request('accountManageSubmitCode', { ...formInfo, phone: `${formInfo.phone}`, code: `${formInfo.code}` })
        );

        sessionStorage.removeItem('BIND_AUTH_CODE_SECOND_DATE');
        ElMessage.success('银行卡绑定成功');
        router.push('/pay/account');
    } finally {
        submitBindLoading.value = false;
    }
};

/* ----------------------------验证码-start---------------------------- */
/**
 * 获取验证码的倒计时
 */
const second = ref(0);
/**
 * 定时器id
 */
const timeid = ref(null);
/**
 * 获取验证码的id
 */
const getAuthCodeLoading = ref(false);
/**
 * 获取短信验证码
 */
const getAuthCode = async () => {
    try {
        getAuthCodeLoading.value = true;
        await formRef.value.validateField(['phone']);

        await withRequestError(
            request('accountManageApplyCode', {
                id,
                account_public: formInfo.account_public,
                phone: `${formInfo.phone}`
            })
        );

        sessionStorage.setItem('BIND_AUTH_CODE_SECOND_DATE', dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'));
        initCountDown();
    } catch (err) {
        if (err?.sub_code === 100) {
            // 已经绑卡的情况下禁用页面
            disabled.value = true;
        }
    } finally {
        getAuthCodeLoading.value = false;
    }
};

/**
 * 初始化验证码倒计时
 */
const initCountDown = (time = 60) => {
    // 存储当前时间。再次刷新进入页面时需要判断是否在60s时间内
    second.value = time;
    timeid.value = setInterval(() => {
        second.value = second.value - 1;
        if (second.value <= 0) {
            clearInterval(timeid.value);
            timeid.value = null;
        }
    }, 1000);
};

/**
 * 验证最长10位
 */
const handleInputNumber = val => {
    val = val.replace(/\D/g, '');
    formInfo.code = Number.parseInt(val) || undefined;
};
/* ----------------------------验证码-end---------------------------- */

/* ----------------------------获取绑卡信息-start---------------------------- */
/**
 * 整体页面的loading
 */
const pageLoading = ref(false);

/**
 * 绑定状态下的话禁用页面的交互
 */
const disabled = ref(false);
const getCardBindInfo = async () => {
    try {
        pageLoading.value = true;
        const { data } = await withRequestError(request('accountManageGetBindCardInfo', { id }));

        // 设置回显内容
        formInfo.account_name = data.account_name;
        formInfo.account_public = data.account_public;
        formInfo.phone = data.account_bank_card_mobile;

        // 如果是绑定状态则禁用页面的按钮和输入框
        if (data.account_bind_status) {
            disabled.value = true;
            return;
        }

        // 设置倒计时的情况，如果是在获取验证码时刷新了页面
        const date = sessionStorage.getItem('BIND_AUTH_CODE_SECOND_DATE');
        if (date) {
            const diffTime = dayjs(new Date()).diff(date);
            // 如果是1分钟之内
            if (diffTime <= 60 * 1000) {
                initCountDown(Number.parseInt((60000 - diffTime) / 1000));
            } else {
                sessionStorage.removeItem('BIND_AUTH_CODE_SECOND_DATE');
            }
        }
    } finally {
        pageLoading.value = false;
    }
};
onBeforeMount(() => {
    getCardBindInfo();
});
/* ----------------------------获取绑卡信息-end---------------------------- */

/* ----------------------------页面初始化布局-start---------------------------- */
onMounted(() => {
    setLayout('pay-sign-layout');
});
onUnmounted(() => {
    resetLayout('pay-sign-layout');
    sessionStorage.removeItem('BIND_AUTH_CODE_SECOND_DATE');
});
/* ----------------------------页面初始化布局-end---------------------------- */
</script>
<style>
.pay-sign-layout {
    height: 100%;
    background-color: #fff;
    padding: 0 16px;
    overflow-y: auto;
}
</style>
<style lang="scss" scoped>
@import './scss/index.scss';
</style>
